﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.ComponentModel;

namespace HiStaff.Util
{
    public class ConvertHelper
    {
        public static int ToInt(object obj)
        {
            try
            {
                if (obj == null) return 0;
                else return Convert.ToInt32(obj);
            }
            catch
            {
                return 0;
            }
        }
        public static string ToString(object obj)
        {
            try
            {
                if (obj == null) return null;
                return obj.ToString();
            }
            catch
            {
                return null;
            }
        }
        public static decimal? ToDecimal(object obj)
        {
            try
            {
                if (obj == null) return null;
                return Convert.ToDecimal(obj);
            }
            catch
            {
                return null;
            }
        }
        public static DateTime? ToDateTime(object obj)
        {
            try
            {
                if (obj == null) return null;
                return Convert.ToDateTime(obj);
            }
            catch
            {
                return null;
            }
        }
        public static String ConvertEnumToString<T>(T eff)
        {

            return System.Enum.GetName(eff.GetType(), eff);

        }

        public static T ConverStringToEnum<T>(string enumValue)
        {
            try
            {
                T result = (T)System.Enum.Parse(typeof(T), enumValue);
                return result;
            }
            catch
            {
                return default(T);
            }
        }

        public static DataTable ListToDataTable<T>(List<T> list)
        {
            DataTable dt = new DataTable(typeof(T).Name);
            foreach (PropertyInfo info in typeof(T).GetProperties())
            {
                if (info.PropertyType == typeof(decimal?))
                    dt.Columns.Add(new DataColumn(info.Name, typeof(decimal)));
                else if (info.PropertyType == typeof(DateTime?))
                    dt.Columns.Add(new DataColumn(info.Name, typeof(DateTime)));
                else if (info.PropertyType == typeof(int?))
                    dt.Columns.Add(new DataColumn(info.Name, typeof(int)));
                else
                    dt.Columns.Add(new DataColumn(info.Name, info.PropertyType));
            }
            foreach (T t in list)
            {
                DataRow row = dt.NewRow();
                foreach (PropertyInfo info in typeof(T).GetProperties())
                {
                    row[info.Name] = info.GetValue(t, null) == null ? DBNull.Value : info.GetValue(t, null);
                }
                dt.Rows.Add(row);
            }
            return dt;
        }

        public static DataTable ObjectToDataTable(object obj)
        {
            try
            {
                if (obj == null) return new DataTable("T");
                else if (obj is DataTable) return (DataTable)obj;
                else if (obj is DataRow)
                {
                    var a = ((DataRow)obj).Table.Clone();
                    a.ImportRow((DataRow)obj);
                    return a;
                }
                else return ObjectToDataTable(obj);
            }
            catch
            {
                return new DataTable("T");
            }
        }
    
        public static string RomanNumerals(int n)
        {
            int i = 0;
            string[] arabic = "1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1".Split(',');
            string[] roman = "M,CM,D,CD,C,XC,L,XL,X,IX,V,IV,I".Split(',');
            string result = "";
            while (n > 0)
            {
                while (n >= Convert.ToInt32(arabic[i]))
                {
                    n = n - Convert.ToInt32(arabic[i]);
                    result = result + roman[i];
                }
                i = i + 1;
            }
            return result;
        }

        public static DataTable EntityToDataTable(object entity)
        {
            DataTable dt = new DataTable(entity.GetType().Name);
            foreach (PropertyInfo info in entity.GetType().GetProperties())
            {
                if (info.PropertyType == typeof(decimal?))
                    dt.Columns.Add(new DataColumn(info.Name, typeof(decimal)));
                else if (info.PropertyType == typeof(DateTime?))
                    dt.Columns.Add(new DataColumn(info.Name, typeof(DateTime)));
                else if (info.PropertyType == typeof(int?))
                    dt.Columns.Add(new DataColumn(info.Name, typeof(int)));
                else
                    dt.Columns.Add(new DataColumn(info.Name, info.PropertyType));
            }
            DataRow row = dt.NewRow();
            foreach (PropertyInfo info in entity.GetType().GetProperties())
            {
                row[info.Name] = info.GetValue(entity, null) == null ? DBNull.Value : info.GetValue(entity, null);
            }
            dt.Rows.Add(row);

            return dt;
        }

        public static T DataRowToEntity<T>(DataRow dataRow) where T : new()
        {
            try
            {
                T objT = new T();
                PropertyDescriptorCollection infos = TypeDescriptor.GetProperties(objT.GetType());
                foreach (DataColumn dc in dataRow.Table.Columns)
                {
                    foreach (PropertyDescriptor info in infos)
                    {
                        if (info.Name.ToUpper() == dc.ColumnName.ToUpper())
                        {
                            object value = dataRow[dc.ColumnName];
                            TypeConverter typeConverter = info.Converter;
                            if (value != DBNull.Value)
                            {
                                object obj = value;
                                if (typeConverter != null)
                                {
                                    if (value.GetType().Name == "Byte[]")
                                    {
                                        obj = value;
                                    }
                                    else
                                        obj = typeConverter.ConvertFromString(value.ToString());
                                }
                                info.SetValue(objT, obj);
                            }
                        }
                    }
                }
                return objT;
            }
            catch(Exception ex)
            {
                Log.Instance.WriteExceptionLog(ex, "DataRowToEntity");
                return default(T);
            }
        }
        
        public static List<T> DataTableToList<T>(DataTable data) where T : new()
        {
            return AutoMapper.Mapper.DynamicMap<IDataReader, List<T>>(data.CreateDataReader());
            //List<T> listT = new List<T>();
            //T objT;
            //foreach (DataRow dr in data.Rows)
            //{
            //    objT = DataRowToEntity<T>(dr);
            //    listT.Add(objT);
            //}
            //return listT;
        }

        public static void TranferValueBetween2Object(Object source, Object destination)
        {
            PropertyDescriptorCollection infoSource = TypeDescriptor.GetProperties(source.GetType());
            PropertyDescriptorCollection infoDestination = TypeDescriptor.GetProperties(destination.GetType());
            if (infoDestination != null && infoDestination.Count > 0)
            {
                foreach (PropertyDescriptor info in infoDestination)
                {
                    info.SetValue(destination, infoSource.Find(info.Name, true).GetValue(source));
                }
            }
        }

        public static string UnicodeToVni(string source)
        {
            string result = null;
            int i = 0;

            var maAcii = new int[]{7845, 7847, 7849, 7851, 7853, 226, 225, 224, 7843, 227,
            7841, 7855, 7857, 7859, 7861, 7863, 259, 250, 249, 7911,
            361, 7909, 7913, 7915, 7917, 7919, 7921, 432, 7871, 7873,
            7875, 7877, 7879, 234, 233, 232, 7867, 7869, 7865, 7889,
            7891, 7893, 7895, 7897, 244, 243, 242, 7887, 245, 7885,
            7899, 7901, 7903, 7905, 7907, 417, 237, 236, 7881, 297,
            7883, 253, 7923, 7927, 7929, 7925, 273, 7844, 7846, 7848,
            7850, 7852, 194, 193, 192, 7842, 195, 7840, 7854, 7856,
            7858, 7860, 7862, 258, 218, 217, 7910, 360, 7908, 7912,
            7914, 7916, 7918, 7920, 431, 7870, 7872, 7874, 7876, 7878,
            202, 201, 200, 7866, 7868, 7864, 7888, 7890, 7892, 7894,
            7896, 212, 211, 210, 7886, 213, 7884, 7898, 7900, 7902,
            7904, 7906, 416, 205, 204, 7880, 296, 7882, 221, 7922,
            7926, 7928, 7924, 272};

            var Vni = new string[]{"aá", "aà", "aå", "aã", "aä", "aâ", "aù", "aø", "aû", "aõ",
            "aï", "aé", "aè", "aú", "aü", "aë", "aê", "uù", "uø", "uû",
            "uõ", "uï", "öù", "öø", "öû", "öõ", "öï", "ö", "eá", "eà",
            "eå", "eã", "eä", "eâ", "eù", "eø", "eû", "eõ", "eï", "oá",
            "oà", "oå", "oã", "oä", "oâ", "où", "oø", "oû", "oõ", "oï",
            "ôù", "ôø", "ôû", "ôõ", "ôï", "ô", "í", "ì", "æ", "ó",
            "ò", "yù", "yø", "yû", "yõ", "î", "ñ", "AÁ", "AÀ", "AÅ",
            "AÃ", "AÄ", "AÂ", "AÙ", "AØ", "AÛ", "AÕ", "AÏ", "AÉ", "AÈ",
            "AÚ", "AÜ", "AË", "AÊ", "UÙ", "UØ", "UÛ", "UÕ", "UÏ", "ÖÙ",
            "ÖØ", "ÖÛ", "ÖÕ", "ÖÏ", "Ö", "EÁ", "EÀ", "EÅ", "EÃ", "EÄ",
            "EÂ", "EÙ", "EØ", "EÛ", "EÕ", "EÏ", "OÁ", "OÀ", "OÅ", "OÃ",
            "OÄ", "OÂ", "OÙ", "OØ", "OÛ", "OÕ", "OÏ", "ÔÙ", "ÔØ", "ÔÛ",
            "ÔÕ", "ÔÏ", "Ô", "Í", "Ì", "Æ", "Ó", "Ò", "YÙ", "YØ",
            "YÛ", "YÕ", "Î", "Ñ"};

            var loi = new string[] {"aauø", "aaø", "aaoõ", "auø", "aoõ", "aeù", "aeø", "auuø", "aeâ", "uuø",
            "uoõ", "öoõ", "eoõ", "AAUØ", "AAØ", "AAOÕ", "AUØ", "AOÕ", "AEÙ", "AEØ",
            "AUUØ", "AEÂ", "UUØ", "UOÕ", "ÖOÕ", "EOÕ"};

            var suaLoi = new string[] {"aá", "aà", "aã", "aù", "aõ", "aé", "aè", "aú", "aê", "uù",
            "uõ", "öõ", "eõ", "AÁ", "AÀ", "AÃ", "AÙ", "AÕ", "AÉ", "AÈ",
            "AÚ", "AÊ", "UÙ", "UÕ", "ÖÕ", "EÕ"};

            result = source;
            for (i = 0; i <= 133; i++)
            {
                result = result.Replace(char.ConvertFromUtf32(maAcii[i]), Vni[i]);
            }

            for (i = 0; i <= 25; i++)
            {
                result = result.Replace(loi[i], suaLoi[i]);
            }
            return result;
        }
        public static string UnicodeToTcvn3(string source)
        {
            char[] tcvnchars = {

        'µ', '¸', '¶', '·', '¹', 

        '¨', '»', '¾', '¼', '½', 'Æ', 

        '©', 'Ç', 'Ê', 'È', 'É', 'Ë', 

        '®', 'Ì', 'Ð', 'Î', 'Ï', 'Ñ', 

        'ª', 'Ò', 'Õ', 'Ó', 'Ô', 'Ö', 

        '×', 'Ý', 'Ø', 'Ü', 'Þ', 

        'ß', 'ã', 'á', 'â', 'ä', 

        '«', 'å', 'è', 'æ', 'ç', 'é', 

        '¬', 'ê', 'í', 'ë', 'ì', 'î', 

        'ï', 'ó', 'ñ', 'ò', 'ô', 

        '­', 'õ', 'ø', 'ö', '÷', 'ù', 

        'ú', 'ý', 'û', 'ü', 'þ', 

        '¡', '¢', '§', '£', '¤', '¥', '¦'};
            char[] unichars = {

        'à', 'á', 'ả', 'ã', 'ạ', 

        'ă', 'ằ', 'ắ', 'ẳ', 'ẵ', 'ặ', 

        'â', 'ầ', 'ấ', 'ẩ', 'ẫ', 'ậ', 

        'đ', 'è', 'é', 'ẻ', 'ẽ', 'ẹ', 

        'ê', 'ề', 'ế', 'ể', 'ễ', 'ệ', 

        'ì', 'í', 'ỉ', 'ĩ', 'ị', 

        'ò', 'ó', 'ỏ', 'õ', 'ọ', 

        'ô', 'ồ', 'ố', 'ổ', 'ỗ', 'ộ', 

        'ơ', 'ờ', 'ớ', 'ở', 'ỡ', 'ợ', 

        'ù', 'ú', 'ủ', 'ũ', 'ụ', 

        'ư', 'ừ', 'ứ', 'ử', 'ữ', 'ự', 

        'ỳ', 'ý', 'ỷ', 'ỹ', 'ỵ', 

        'Ă', 'Â', 'Đ', 'Ê', 'Ô', 'Ơ', 'Ư'};

            char[] convertTable = new char[255];
            for (int i = 0; i < 256; i++)
            {
                convertTable[i] = (char)i;
            }
            for (int i = 0; i < tcvnchars.Length; i++)
            {
                convertTable[unichars[i]] = tcvnchars[i];
            }

            char[] chars = source.ToCharArray();

            for (int i = 0; i < chars.Length; i++)

                if (chars[i] < (char)256)

                    chars[i] = convertTable[chars[i]];

            return new string(chars);

        }
    }
}
